package org.example.reflection;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

/**
 * @author: ZhuYouBin
 * @date: 2022/4/7 15:25
 * @description:
 */
public class MethodDemo {
    public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException,
            InstantiationException, IllegalAccessException,
            InvocationTargetException {
        // 1、获取Class类对象
        Class<?> clazz = Class.forName("org.example.reflection.Student");
        // 2、创建实例对象
        // 这里先默认通过构造方法创建实例对象，后面会继续介绍如何创建对象
        Student student = (Student) clazz.newInstance();
        // 3、获取需要调用的方法
        Method method = clazz.getDeclaredMethod("subTest04", String.class);
        // 调用invoke(Object obj, Object... args)方法, obj表示实例对象，args表示调用方法的参数
        Object ret = method.invoke(student, "这是一个方法参数");
        System.out.println("方法的返回值是：" + ret);
    }

    static void test01() throws ClassNotFoundException, NoSuchMethodException {
        // 1、获取Class类对象
        Class<?> clazz = Class.forName("org.example.reflection.Student");
        // 2、获取类中方法
        // getMethods(): 获取当前类、父类中所有的public方法
        Method[] methods = clazz.getMethods();
        System.out.println("===== getMethods(): 获取当前类、父类中所有的public方法 =====");
        for (Method method : methods) {
            System.out.println(method);
        }
        System.out.println();

        // getDeclaredMethods(): 获取当前类中的所有方法
        Method[] declaredMethods = clazz.getDeclaredMethods();
        System.out.println("===== getDeclaredMethods(): 获取当前类中的所有方法 =====");
        for (Method declaredMethod : declaredMethods) {
            System.out.println(declaredMethod);
        }
        System.out.println();

        // getMethod(String name, Class<?> paramType): 获取当前类、父类中一个指定方法名称的public方法
        System.out.println("===== getMethod(String name, Class<?> paramType): 获取当前类、父类中一个指定方法名称的public方法 =====");
        // 方法没有参数,则设置null即可
        Method test04 = clazz.getMethod("test04", null);
        System.out.println("父类中public方法: "+test04);
        // 有参数,则传递参数类型
        Method subTest04 = clazz.getMethod("subTest04", String.class);
        System.out.println("子类中public方法: "+subTest04);

        System.out.println();
        // getDeclaredMethod(String name, Class<?> paramType): 获取当前类中一个指定方法名称的方法
        System.out.println("===== getDeclaredMethod(): 获取当前类中一个指定方法名称的方法 =====");
        Method subTest01 = clazz.getDeclaredMethod("subTest01", null);
        System.out.println("当前类中私有方法: "+subTest01);
    }
}
